home *** CD-ROM | disk | FTP | other *** search
/ Lattice ISP Synario Start… & ISP Encyclopedia 1997 / LATTICE Synario.iso / ispcode / source / icode5d.c < prev    next >
Encoding:
Text File  |  1997-06-24  |  35.6 KB  |  802 lines

  1. /****************************************************************************
  2. *                            ispCODE5D.c                                    *
  3. *                   ispCODE for ispLSI 2000V Devices                        *
  4. *              Lattice Semiconductor Corp. Copyright 1996.                  *
  5. *                                                                           *
  6. * ISP(tm) daisy chain turbo programming is supported by ispCODE.            *
  7. *                                                                           *
  8. * The function of ispCODE is to step the IEEE 1149.1 TAP state machine      *
  9. * in the ispLSI devices for programming and verification. The input file    *
  10. * for ispCODE is SLIM ispSTREAM file.                                            *
  11. *                                                                           *
  12. * The file size of SLIM ispSTREAM is at least 50% less than the FULL        *
  13. * ispSTREAM. The saving comes from stripping out the instructions and field *
  14. * size identifiers. The code size of ispCODE V5.00 for processing the SLIM  *
  15. * ispSTREAM is also reduced by 50% as a result.                             *
  16. *                                                                           *
  17. * The file size of Super SLIM ispSTREAM is about 50% less than the SLIM     *
  18. * ispSTREAM. The extra saving comes from replacing long chain of 0xFFs with *
  19. * the number of consecutive 0xFF bytes. For example:                        *
  20. *           0xFF,0xFF,0xFF,0xC3 is reduced to 0xFF,0x02,0xC3                *
  21. *                                                                           *
  22. * The only restriction on the SLIM ispSTREAM is that the daisy chain must be*
  23. * of the same ISP device types. For example:                                *
  24. *                  A chain of ispLSI 2000V devices.                          *
  25. *                                                                           *
  26. * The SLIM ispSTREAM file is created by the command line program dld2isp.exe*
  27. * v4.02 with the option s selected. For example: type                       *
  28. *                  dld2isp  design.dld s                                    *
  29. * The Super SLIM ispSTREAM file is created by the command line program      *
  30. * dld2isp.exe v4.03 with the option ss selected. For example: type          *
  31. *                  dld2isp  design.dld ss                                   *
  32. *                                                                           *
  33. * The program isp2hex.exe and the source code isp2hex.c can be used to      *
  34. * convert the ispSTREAM file from binary format to C code for linking with  *
  35. * ispcode5.c.                                                               *
  36. *                                                                           *
  37. * All ispLSI 2000LV family of devices support the IEEE 1149.1 32-bit        *
  38. * USERCODE. The USERCODE data must be appended into the JEDEC file if it    *
  39. * is to be programmed into the device. The UES editor on the ISP Daisy      *
  40. * Chain Download should be used to add or modify the USERCODE data.         *
  41. * It is important to note that USERCODE is only 32 bits long. The extra     *
  42. * bits will still be written into the JEDEC file but will be discarded      *
  43. * during USERCODE programming if more than 32 bits of data is entered       *
  44. * on the UES editor.                                                        *
  45. *                                                                           *
  46. * Programming and verification always include all Array Cells and the       *
  47. * entire USERCODE. The USERCODE is programmed to be FFFFFFFF in hex by      *
  48. * default.                                                                  *
  49. *                                                                           *
  50. * The procedure of reading USERCODE is as follows:                          *
  51. * 1. Raise TMS to VIH and pulse TCK 6 times to step to Test-Logic Reset     *
  52. *    state.                                                                    *
  53. * 2. TMS to VIL, pulse TCK 1 time.                                          *
  54. * 3. TMS to VIH, pulse TCK 2 times.                                         *
  55. * 4. TMS to VIL, pulse TCK 2 times to step to Shift-IR state.               *
  56. * 5. TMS stay at VIL, shift in the VERIFY_USERCODE instruction 10111        *
  57. *    into the IR via TDI and pulse TCK. The instruction is shifted in       *
  58. *    from right to left, i.e. 1, 1, 1, 0 and 1. Repeat the instruction      *
  59. *    if there is more than one ispLSI device in the chain. Raise TMS to     *
  60. *    VIH while shifting in the last bit.                                    *
  61. * 6. Keep TMS at VIH, pulse TCK 2 times to step to Select-DR-Scan state.    *
  62. * 7. TMS to VIL, pulse TCK 2 times to step to Shift-DR state.               *
  63. * 8. Keep TMS at VIL, pulse TCK 32 times to shift out the 32 bits           *
  64. *    USERCODE on TDO. Pulse TCK 32 times more if more than one device       *
  65. *    in the chain. Raise TMS to VIH while shifting out the last bit.        *
  66. *                                                                           *
  67. * 9. Keep TMS at VIH and pulse TCK 6 times to go back to Test-Logic         *
  68. *    Reset state to end the procedure.                                      *
  69. *                                                                           *
  70. * Revision history:                                                         *
  71. *   5D.000 Howard Tang   11/12/96 Convert from 5C.0 to support programming  *
  72. *                                 using the IEEE 1149.1 TAP for ispLSI      *
  73. *                                 2000LV family of devices.                 *
  74. *****************************************************************************/
  75.  
  76. #include <stdio.h>
  77. #include <dos.h>
  78. #include <stdlib.h>
  79. #include <string.h>
  80. #include "lattice.h"
  81. #include "istream.hex"
  82.  
  83. /*Global variables */
  84. static unsigned char curch;        /*the current data from ispSTREAM*/
  85. unsigned char *fp;                 /*pointer to the ispSTREAM*/
  86. static short int      bit=0;       /*the current bit read from ispSTREAM*/
  87.  
  88. static short int inputport=inport1,       /*port address for the input port*/
  89.                  outputport=outport1;      /*port address for the output port*/
  90. static short int isp_pins=NUL;    /*3.02 holds the value of parallel port*/
  91.                                  /*     intialized to drive all pins to LOW*/
  92. static char     state;           /*4.0  Keep track of the state of the TAP
  93.                                         state machine.*/
  94. /*prototypes*/
  95. void            pulse_width(unsigned short int milliseconds);
  96. void            execute(void);
  97. void            move_to_id_state(void);
  98. short int       ispstream_pump(short int operation, short int *end);
  99. void            error_handler(short int rcode, char *message);
  100. unsigned char   GetByte(void);
  101. void ReadispSTREAMHeader(short int *ChainLength, short int *ErasePulse, 
  102.                          short int *ProgramPulse, short int *RowLength, 
  103.                          unsigned short int *DataSize, 
  104.                          unsigned short int *IDStreamLength);
  105. char ispRead(unsigned short int DataSize, unsigned char *OutData);
  106. void ReadispSTREAMData(unsigned short int DataSize, unsigned char *InData,
  107.                        char SS);
  108. void ispInstruction(short int ChipCount, unsigned char Command);
  109. void ispAddress(short int ChipCount, short int RowLength);
  110. void ispData( unsigned char *InData, unsigned short int DataSize);
  111. void program_enable(short int chips);
  112. void device_enable(short int chips);
  113.  
  114. /***************************************************************************
  115.    Function: isp_setpin(byte pins, byte value)
  116.  
  117.    Purpose:
  118.    To apply the specified value to the pins indicated. This routine will
  119.    likely be modified for specific systems. As an example, this code
  120.    is for the PC, as described below.
  121.  
  122.    This routine uses the IBM-PC standard Parallel port, along with the
  123.    schematic shown in Lattice documentation, to apply the signals to the
  124.    programming loop. 
  125.  
  126.    PC Parallel port pin    Signal name
  127.    --------------------    -----------
  128.          2                   out_SDI
  129.          3                   out_SCLK
  130.          4                   out_MODE
  131.          5                   out_ISP
  132.          6                   out_RESET
  133.          7                   DO5
  134.          8                   out_SENSE_CABLE_OUT    
  135.          9                   DO7
  136.          10                  in_SDO
  137.          12                  in_CABLE_SENSE_IN
  138.          15                  in_VCC_OK 
  139.          20                  GND
  140.  
  141.    Parameters:
  142.          - pins, which is actually a set of bit flags (defined in lattice.h) 
  143.            that correspond to the bits of the data port. Each of the I/O port 
  144.            bits that drives an isp programming pin is assigned a flag 
  145.            (through a #define) corresponding to the signal it drives. To 
  146.            change the value of more than one pin at once, the flags are added 
  147.            together, much like file access flags are.
  148.  
  149.            The bit flags are only set if the pin is to be changed. Bits that 
  150.            do not have their flags set do not have their levels changed. The 
  151.            state of the port is always manintained in the static global 
  152.            variable isp_pins, so that each pin can be addressed individually 
  153.            without disturbing the others.
  154.  
  155.          - value, which is either HIGH (0x01 ) or LOW (0x00 ). Only these two
  156.            values are valid. Any non-zero number sets the pin(s) high.
  157.  
  158.    Returns: nothing.
  159.  
  160.  
  161. **************************************************************************/
  162. void isp_setpin(unsigned char pins, unsigned char value)
  163. {
  164.   /* isp_pins is a Global value that keeps track of the current state
  165.      of the pins  */
  166.  
  167.   if( value ) /* set flagged pins HIGH */
  168.       isp_pins = pins | isp_pins;
  169.   else        /* set flagged pins LOW */
  170.       isp_pins = ~pins & isp_pins;
  171.  
  172.   /* value is put on Parallel port pins */
  173.   outp(outputport, isp_pins);
  174.  
  175. } /* isp_setpin() */
  176.  
  177.  
  178. /***************************************************************************
  179.    Function: isp_SDO()
  180.  
  181.    Purpose:
  182.    To get the value of the SDO pin from the input port.
  183.  
  184.    This routine is specific to the PC parallel port setup, but can easily
  185.    be changed to address each user's hardware.
  186.  
  187.    Parameters: none
  188.  
  189.    Returns: The value of SDO, as a byte, with a value of either 0 or 1.
  190.  
  191.    Notes:
  192.    - This routine uses the I/O port addresses contained in the global
  193.      variable inputport, declared in the lattice.h file. 
  194.  
  195. ****************************************************************************/
  196. unsigned char isp_SDO(void)
  197. {
  198.  /* MUST return either 0x00 or 0x01 */
  199.   return( (unsigned char) ((inp(inputport) & in_SDO ) ? HIGH : LOW) );
  200.  
  201. } /* isp_SDO() */
  202.  
  203. /*************************************************************
  204. *                                                            *
  205. *                         PULSE_WIDTH                        *
  206. * This procedure produce accurate timing only on straight PC *
  207. * DOS. The timing is not guarantee if use on Windows DOS.    *
  208. * The delay() function is available only from BORLAND.       *
  209. *                                                            *
  210. * Users must devise their own timing procedures to ensure    *
  211. * the specified minimum delay is observed when using         *
  212. * different platform.                                        *
  213. *************************************************************/
  214.  
  215.  
  216. void            pulse_width(unsigned short int milliseconds)
  217. {
  218.                 delay(milliseconds);
  219. }
  220.  
  221. /*************************************************************
  222. *                                                            *
  223. *                      GETBYTE                               *
  224. * This procedure reads a byte from the ispSTREAM.            *
  225. *************************************************************/
  226. unsigned char GetByte()
  227. {
  228.  return (*fp++);
  229. }
  230.  
  231.  
  232. /*************************************************************
  233. *                                                            *
  234. *                      SCLOCK                                *
  235. * This procedure apply a clock to TCK.                       *
  236. *************************************************************/
  237. void sclock(void)
  238. {
  239.  isp_setpin(out_SCLK,HIGH);
  240.  isp_setpin(out_SCLK,LOW);
  241. }
  242.  
  243. /*************************************************************
  244. *                                                            *
  245. *                       SHIFT/EXECUTE                        *
  246. * This procedure walk all devices in the daisy chain from a  *
  247. * given state to the next desirable state.                   * 
  248. *                                                            *
  249. *If at Idle state when enter then move to Shift-IR state.    *
  250. *If at Shift-IR state when enter then move to Shift-DR state.*
  251. *If at Shift-DR state when enter then move to Shift-IR state.*
  252. *If at Shift-IR state and state is set to time_state when    *
  253. *enter then move to Idle state.                              *
  254. *************************************************************/
  255. void execute()
  256. {
  257.  short int i,count;
  258.      if (state==time_state) 
  259.         {count = 1;   /*move from shift-IR to Idle state to start timing*/ 
  260.          state = idle_state;
  261.         }
  262.      else if (state==shift_state) 
  263.              {count = 2;  /*move from shift-IR to shift-DR*/
  264.               state = execute_state;
  265.              } 
  266.      else if (state==idle_state)
  267.              {count = 2;  /*move from Idle to shift-IR state*/
  268.               state = shift_state;
  269.              }
  270.      else if (state==execute_state)
  271.              {count = 3;  /*move from shift-DR to shift-IR*/
  272.               state = shift_state;
  273.              }
  274.      else count = 0;
  275.      isp_setpin(out_SCLK,LOW);
  276.      isp_setpin(out_MODE,LOW);
  277.      isp_setpin(out_SDI,LOW);
  278.      for (i=0; i<count; i++)
  279.          {
  280.           isp_setpin(out_MODE,HIGH);
  281.           sclock();
  282.          }
  283.      isp_setpin(out_MODE,LOW);
  284.      sclock();
  285.      if (count > 1) sclock();
  286.        /* at Shift-DR or Shift-IR state*/
  287.  
  288. }
  289.  
  290.  
  291. /*************************************************************
  292. *                                                            *
  293. *                      MOVE TO ID STATE                      *
  294. * This procedure walk all devices in the daisy chain to the  *
  295. * Test-Logic-Reset state then Run-Test/Idle state.           *
  296. *                                                            *
  297. *************************************************************/
  298.  
  299. void move_to_id_state()
  300. {
  301. short int i;
  302.        isp_setpin(out_SCLK,LOW);
  303.        isp_setpin(out_MODE+out_SDI,LOW);
  304.        pulse_width(2);
  305.        isp_setpin(out_MODE,HIGH);            
  306.        pulse_width(2);
  307.        isp_setpin(out_SCLK,HIGH);
  308.        pulse_width(2);
  309.        isp_setpin(out_SCLK,LOW);
  310.        for (i=0; i<6; i++) sclock();
  311.        isp_setpin(out_MODE,LOW);
  312.        pulse_width(2);
  313.        sclock();   /*device is in Idle state*/
  314.        state = idle_state;
  315. }
  316.  
  317. /*************************************************************
  318. *                                                            *
  319. *                      PROGRAM ENABLE                        *
  320. * perform the 3 read id instruction to get devices into      *
  321. * programming mode.                                          *
  322. *************************************************************/
  323.  
  324. void program_enable(short int chips)
  325. {
  326. short int i,j,loops;
  327.  
  328. for (loops=0; loops<3; loops++)
  329.     {
  330.      for (i=0; i<chips+1; i++)
  331.          for (j=0; j<5; j++)  /*send the instruction into TDI*/
  332.              {if ((i==chips)&&(j==4)) isp_setpin(out_MODE,HIGH);  /*last bit*/ 
  333.               isp_setpin(out_SDI,(PROGRAM_ENABLE >> j) & 0x01);
  334.               sclock();
  335.              }     
  336.      for (i=0; i<3; i++) sclock();
  337.      isp_setpin(out_MODE,LOW);
  338.      sclock(); sclock(); /*devices at Shift-IR state*/
  339.      
  340.     }     
  341. }
  342.  
  343. /*************************************************************
  344. *                                                            *
  345. *                      DEVICE ENABLE                         *
  346. * perform the read id instruction to get devices into        *
  347. * functional mode.                                           *
  348. *************************************************************/
  349.  
  350. void device_enable(short int chips)
  351. {
  352. short int i,j;
  353.  
  354. /*devices come in at Shift-IR state*/
  355.      for (i=0; i<chips+1; i++)
  356.          for (j=0; j<5; j++)  /*send the instruction into TDI*/
  357.              {if ((i==chips)&&(j==4)) isp_setpin(out_MODE,HIGH);  /*last bit*/ 
  358.               isp_setpin(out_SDI,(PROGRAM_ENABLE >> j) & 0x01);
  359.               sclock();
  360.              }     
  361.      sclock();                /*devices at Update-IR state*/
  362.      isp_setpin(out_MODE,LOW);
  363.      for (i=0; i<20; i++) sclock();   /*go and loop on Run-Test/Idle for 10uS*/
  364.      isp_setpin(out_MODE,HIGH);
  365.      for (i=0; i<3; i++) sclock();   /*devices at Test-Logic-Reset and active*/
  366. }     
  367.  
  368. /*************************************************************
  369. *                                                            *
  370. *                     READ_ISPSTREAM_HEADER                  *
  371. * Extract the header from the ispSTREAM file.                *
  372. * Return                                                     *
  373. *     ChainLength--------number of ispLSI devices in the     *
  374. *                        given daisy  chain.                 *
  375. *     ErasePulse---------pulse width in mS for device        *
  376. *                        bulk erase.                         *
  377. *     ProgramPulse-------pulse width in mS for device        *
  378. *                        row by row programming.             *
  379. *     RowLength----------the number of rows of data +UES     *
  380. *     DataSize-----------the size of each row of data        *
  381. *     IDStreamLength-----the bit length of the ID stream.    *
  382. *************************************************************/
  383. void ReadispSTREAMHeader(short int *ChainLength, short int *ErasePulse, 
  384.                          short int *ProgramPulse, short int *RowLength,
  385.                          unsigned short int *DataSize,
  386.                          unsigned short int *IDStreamLength)
  387. {
  388.    
  389.    *ChainLength = GetByte();              
  390.    *ErasePulse = GetByte() * 0x100;
  391.    *ErasePulse += GetByte();
  392.    *ProgramPulse = GetByte(); 
  393.    *RowLength = GetByte() * 0x100;
  394.    *RowLength += GetByte();
  395.    *DataSize = GetByte() * 0x100;
  396.    *DataSize += GetByte();   
  397.    *IDStreamLength = GetByte() * 0x100;
  398.    *IDStreamLength += GetByte();
  399.    /*End of the header of the ispSTREAM file.*/   
  400.    
  401. }
  402.  
  403. /*****************************************************************
  404. *                                                                *
  405. *                     READ_ISPSTREAM_DATA                        *
  406. * Extract the data from the ispSTREAM file.                      *
  407. *     DataSize-----------The number of data bits to be fetched.  *
  408. *     SS-----------------Super SLIM ispSTREAM file if true.      *
  409. * Return                                                         *
  410. *     InData-------------The data stream from ispSTREAM file     *
  411. ******************************************************************/
  412. void ReadispSTREAMData(unsigned short int DataSize, unsigned char *InData, 
  413.                        char SS)
  414. {
  415.  unsigned short int index;
  416.  short  int i,j;
  417.  unsigned char xch;
  418.  static short int FFcount=0; /*5.1*/
  419.  
  420.  j=0;
  421.  xch=0;
  422.  for (index=0; index<DataSize; index++)
  423.      {--bit;
  424.       if (bit<0) 
  425.          {if (FFcount<=0) /*5.1 Read a new byte if 0xFF chain exhausted*/
  426.              { curch = GetByte(); 
  427.                if ((SS)&&(curch==0xFF)) /*5.1 Super SLIM ispSTREAM file support*/
  428.                FFcount = GetByte();     /*5.1 The number of 0xFF bytes*/
  429.              }
  430.           else FFcount--; /*5.1 Use up the 0xFF chain first*/
  431.           bit=7;
  432.          }
  433.       if ((curch >> bit) & 0x01)  xch |= 0x80 >> index%8;                
  434.       if (index%8==7) {InData[j++] = xch; xch=0;}
  435.      }  
  436.    InData[j] = xch;   /*save the last byte of the current row*/
  437. }
  438.  
  439. /*************************************************************
  440. *                                                            *
  441. *                     ispInstruction                         *
  442. * Send the instruction streams to the devices.               *
  443. *    ChipCount-------The number of devices in the chain.     *
  444. *    Command---------The command to be sent to all devices.  *
  445. *************************************************************/
  446. void ispInstruction(short int ChipCount, unsigned char Command)
  447. {
  448.  char Instruction = 5;       /*All Lattice devices have 5 bit commands*/
  449.  short int index;
  450.  short int i;
  451.  for (index = 0; index < ChipCount; index++) { 
  452.       for (i=0; i<Instruction; i++)
  453.           {isp_setpin(out_SDI, (Command >> i)&0x01); 
  454.            if ((index==ChipCount-1)&&(i==Instruction-1)) 
  455.               isp_setpin(out_MODE,HIGH);  /*shift in the last bit*/
  456.            sclock();  /*clock the data into the command registers */
  457.           }
  458.       }
  459.  execute();
  460. }
  461.  
  462. /*************************************************************
  463. *                                                            *
  464. *                     ispAddress                             *
  465. * Send the Address streams to the devices.                   *
  466. *    ChipCount-------The number of devices in the chain.     *
  467. *    Address---------The full address for the devices.       *
  468. *************************************************************/
  469. void ispAddress(short int ChipCount, short int RowLength)
  470. {
  471.  short int index;
  472.  short int i;
  473.  unsigned short int condition;    /*0x1000 HD devices*/
  474.                                   /*0x2000 HD devices with UES*/
  475.                             /*0x3000 Single row per address HD devices*/
  476.                             /*0x4000 Single row per address HD devices with UES*/
  477.  
  478.  condition = RowLength & 0xF000;
  479.  RowLength = RowLength & 0x0FFF;      /*Mask out the condition bits*/  
  480.  if ((condition==0x2000)||(condition==0x4000)) 
  481.     RowLength = (RowLength-1)/2;      /*Exclude the USERCODE from address*/
  482.  else if ((condition==0x1000)||(condition==0x3000))
  483.     RowLength = RowLength/2;          /*High Low Order addressing*/
  484.  
  485.  for (index = 0; index < ChipCount; index++) { 
  486.       for (i=1; i<RowLength; i++)
  487.            sclock();  /*clock  zeros into the address registers */
  488.       isp_setpin(out_SDI,HIGH);
  489.       if (index==ChipCount-1) 
  490.          isp_setpin(out_MODE,HIGH);  /*shift in the last bit*/
  491.       sclock();       /*clock a one into the address registers*/
  492.       isp_setpin(out_SDI,LOW);
  493.       }
  494.  execute();   /*step to shift-IR state*/ 
  495. }
  496.  
  497. /**********************************************************************
  498. *                                                                     *
  499. *                     ispData                                         *
  500. * Send the data stream to devices.                                    *
  501. *    InData-----------The data stream to be sent to devices.          *
  502. *    DataSize---------The length of the data stream.                  *
  503. ***********************************************************************/
  504. void ispData(unsigned char *InData, unsigned short int DataSize)
  505. {
  506.  unsigned short int index;
  507.  short int i,j;
  508.  unsigned char xch;
  509.  
  510.  j=0;
  511.  for (index = 0; index <DataSize; index++) { 
  512.       if (index%8==0) xch = InData[j++];
  513.       isp_setpin(out_SDI, (((xch << index%8) & 0x80) ? 0x01 : 0x00)); 
  514.       if (index==DataSize-1) 
  515.          isp_setpin(out_MODE,HIGH);  /*shift in the last bit*/
  516.       sclock();  /*clock data into the data shift registers */
  517.       }
  518.  execute();   /*step to shift-IR state*/ 
  519. }
  520.  
  521. /**********************************************************************
  522. *                                                                     *
  523. *                     ispRead                                         *
  524. * Read the data stream from devices and verify.                       *
  525. *    DataSize---------The length of the data stream.                  *
  526. *    OutData----------The data stream to be compare with those read   *
  527. *                     from devices.                                   *
  528. ***********************************************************************/
  529. char ispRead(unsigned short int DataSize, unsigned char *OutData)     
  530. {
  531.  unsigned short int index,error;
  532.  short int i,j;
  533.  unsigned char xch,cur_bit;
  534.  
  535.  j=0;
  536.  error=0;
  537.  xch=0;
  538.  for (index = 0; index <DataSize; index++) { 
  539.       if (index%8==0) xch = OutData[j++];
  540.       cur_bit=isp_SDO(); 
  541.       if (cur_bit != (((xch << index%8) & 0x80) ? 0x01 : 0x00)) 
  542.          error++; 
  543.       if (index==DataSize-1) 
  544.          isp_setpin(out_MODE,HIGH);  /*shift in the last bit*/
  545.       sclock();  /*clock data out from the data shift registers */
  546.       }
  547.  execute();   /*step to shift state*/ 
  548.  if (error > 0) return 1;      /*Flag failure occur*/
  549.  else return (0);
  550. }
  551.  
  552. /*************************************************************
  553. *                                                            *
  554. *                     ISPSTREAM_PUMP                         *
  555. *                                                            *
  556. *************************************************************/
  557.  
  558. short int   ispstream_pump(short int operation, short int *end)
  559. {
  560.    short int       row;
  561.    short int       HighLow;               /*device types identifiers*/  
  562.    char            SS;                    /*ispSTREAM file types identifier*/
  563.    unsigned char   Command,UES,FileType;
  564.    short int       last_row,
  565.                    erase_pulse,
  566.                    program_pulse,
  567.                    devices_in_chain;
  568.    unsigned short int    maxi_data,
  569.                          data_length,
  570.                             id_length;
  571.    short int       rcode;
  572.    short int       DeviceType,EndRow;
  573.    unsigned char   *buf;
  574.  
  575.    row =0;
  576.    bit = 0;
  577.    /*Start reading the header of the ispSTREAM file*/
  578.    fp = ispstream;
  579.    FileType = GetByte();
  580.    if (FileType == 0x01) {SS=false;}          /*Check for correct file type*/
  581.    else if (FileType == 0x03 ) {SS=true;}     /*Super SLIM ispSTREAM file found*/ 
  582.    else {
  583.         return FILE_NOT_JEDEC;
  584.        }
  585.    ReadispSTREAMHeader(&devices_in_chain, &erase_pulse, &program_pulse,
  586.                            &last_row, &maxi_data, &id_length);
  587.  
  588.    rcode = OK;                                /*Success by default.*/
  589.    DeviceType = last_row & 0xF000;            /*Device types code*/
  590.    EndRow = last_row & 0x0FFF;                /*Actual address length*/
  591.    if ((DeviceType == 0x1000) || (DeviceType == 0x2000))
  592.       HighLow = true;                       /*Devices need High/Low addressing  detected*/
  593.    else HighLow = false; 
  594.    if ((DeviceType==0x2000)||(DeviceType==0x4000))
  595.       UES=true;                             /*UES programming required*/
  596.    else UES=false;
  597.    if ((operation==verify)||(operation==verify_ues))    /*verify only*/
  598.       {erase_pulse=0;                       /*void the erase instruction*/ 
  599.        program_pulse=0;                     /*void the program instruction*/
  600.       }
  601.    if ((operation==verify_ues)&&(!UES))     /*The ispSTREAM has no UES*/
  602.       return FILE_NOT_JEDEC;
  603.    
  604.    /*Allocate memory to store one row of data from the ispSTREAM file.*/
  605.    buf = buffer;
  606.    isp_pins = NUL;          /* intialize to drive all port pins LOW*/
  607.    isp_setpin(out_ISP, LOW);/* drive ispEN pin low to enable the 
  608.                                    ispJTAG controlling pins:
  609.                                    TCK,TMS,TDI and TDO.*/ 
  610.    move_to_id_state();      /* Go to Reset then Run-Test/Idle state*/
  611.    isp_setpin(out_MODE,HIGH); 
  612.    sclock();
  613.    isp_setpin(out_MODE,LOW);
  614.    sclock(); sclock();
  615.    state=execute_state;     /* At shift-DR state*/
  616.    isp_setpin(out_SDI,HIGH);
  617.    ReadispSTREAMData(id_length,buf,SS);      /*fetch ID stream from ispSTREAM*/
  618.    rcode = ispRead(id_length,buf);          /*verify the ID stream*/    
  619.    if (rcode != OK)     
  620.        return UNKNOWN_CHIP;      
  621.    program_enable(devices_in_chain);
  622.    if (erase_pulse > 0)                         /*erase the devices*/
  623.       {
  624.        Command = ERASE_ALL;
  625.        state=time_state;
  626.        ispInstruction(devices_in_chain,Command);   
  627.        sclock();                    /*start the erase timing*/
  628.        pulse_width(erase_pulse);    /*erase pulse*/
  629.        isp_setpin(out_MODE, HIGH);
  630.        isp_setpin(out_SCLK,HIGH);
  631.        pulse_width(1);              /*super voltage discharge*/
  632.        isp_setpin(out_SCLK,LOW);
  633.        sclock();
  634.        isp_setpin(out_MODE,LOW);    
  635.        sclock(); sclock();          /*devices in shift state*/
  636.        state=shift_state;
  637.       }
  638.    if (operation==verify_ues)                   /*verify ues only*/
  639.       {for (row=1; row<EndRow; row++)           /*skip array data */
  640.            {
  641.             if ((!HighLow)&&(row%2==0))/*single address per row HD devices*/
  642.                {}                               /*devices have no Low Order rows*/
  643.             else
  644.                ReadispSTREAMData(maxi_data,buf,SS); /*fetch and trash ispSTREAM*/
  645.            }
  646.        }
  647.    else row =1;       
  648.  
  649.  
  650.    /*start processing the rows in the ispSTREAM file*/
  651.  
  652.    for (; row <= EndRow; row++) {
  653.       *end = row;                               /* The row number where process ended.*/
  654.        if ((!HighLow)&&(row%2==0))/*single address per row HD devices*/
  655.           {}                                    /*devices have no Low Order rows*/
  656.        else {                                   
  657.              if (row%2==1)                      /* Addressing for ispLSI devices*/
  658.                 {
  659.                  ispInstruction(devices_in_chain,SHIFT_ADDRESS);
  660.                  if (row==1)                          /* Full addressing once*/ 
  661.                     ispAddress(devices_in_chain,last_row);  
  662.                  else {
  663.                  isp_setpin(out_MODE,HIGH);
  664.                  sclock(); execute();}          /*shift to next address*/
  665.                  }             
  666.             data_length = maxi_data;
  667.             ReadispSTREAMData(data_length,buf,SS); /*fetch data stream from ispSTREAM*/
  668.             Command = SHIFT_DATA;
  669.             ispInstruction(devices_in_chain,Command);
  670.             ispData(buf,data_length);         /*send data into devices*/
  671.             if (program_pulse > 0)               /*program and verify*/
  672.                {
  673.                 if ((HighLow)&&(row%2==0))      /*Low Order rows*/
  674.                    Command = PROGRAM_LOW;
  675.                 else Command = PROGRAM_HIGH;
  676.                 if ((UES)&&(row==EndRow)) Command = PROG_USERCODE;
  677.                 state=time_state;
  678.                 ispInstruction(devices_in_chain,Command);
  679.                 sclock();                       /*start program timing*/
  680.                 pulse_width(program_pulse);
  681.                 execute();                      /*step to shift state*/
  682.                } 
  683.             if ((HighLow)&&(row%2==0))          /*Low Order rows*/
  684.                 Command = VERIFY_LOW_PROG;
  685.             else Command = VERIFY_HIGH_PROG;
  686.             if ((UES)&&(row==EndRow)) Command = VERIFY_USERCODE;
  687.             state=time_state;
  688.             ispInstruction(devices_in_chain,Command);
  689.             sclock();                           /*start verify timing*/
  690.             pulse_width(1);                     /*30uS min. verify time*/
  691.             execute();                          /*step to shift state*/
  692.             Command = SHIFT_DATA;
  693.             ispInstruction(devices_in_chain,Command);
  694.             rcode = ispRead(data_length,buf);   /*verify the data stream*/
  695.             if (rcode != OK)  break;
  696.            }
  697.       }        
  698.    device_enable(devices_in_chain);  /*activate the devices*/
  699.    isp_setpin(out_ISP,HIGH);  /*activate the ispLSI devices*/
  700.    if (rcode==OK) return (OK);
  701.    else return VALIDATION_ERROR;      
  702.  
  703. }
  704.  
  705. /*************************************************************
  706. *                                                            *
  707. *                         error_handler                      *
  708. *                                                            *
  709. *  rcode                  - error code                       *
  710. *                                                            *
  711. *                                                            *
  712. *  This procedure return the address of the message string   *
  713. *  for the corresponding error code.                         *
  714. *                                                            *
  715. *************************************************************/
  716.  
  717. void error_handler(short int rcode, char *message)
  718. {
  719.  
  720. char *error_message[] = {{"PASS"},{""},{""},{"PC Hardware Problem"},{""},
  721.                    {""},{""},
  722.                    {"No Device Found/Open Download Cable/Open Daisy Chain"},
  723.                    {"Can't Find the File"},{""},{"Not Enough PC Memory"},
  724.                    {"Verification Fail"},{""},{""},
  725.                    {""},
  726.                    {"The Chip Count in the Chain and the File Do Not Match"},
  727.                    {"Unknown Device Found"},{"Wrong File Type"},{"File Error"},
  728.                    {""}};
  729.  
  730.  strcpy(message, error_message[-rcode]);
  731.  
  732.  
  733.  
  734. /*************************************************************
  735. *                                                            *
  736. *                            MAIN                            *
  737. *                                                            *
  738. *************************************************************/
  739.  
  740. short int             main(short int argc, char *argv[])
  741. {
  742.    short int       rcode = OK,
  743.                    end = 0;
  744.    char            str[300];
  745.    
  746.    int operation=prog_verify;  /*3.05 Default to Program and Verify*/
  747.    
  748.    printf("\n                 Lattice Semiconductor Corp.\n");
  749.    printf("\n               ispCODE V5D.000 Copyright 1996\n");
  750.    printf("\n         Slim ispSTREAM Driver for ispLSI 2000V Devices\n");
  751.    printf("\n    For Simple Chain of ISP Devices On JTAG TAP Controller\n\n");
  752.  
  753.    if ((argc < 1) || (argc > 2)) {
  754.       printf("\nUsage: sjturbo [operation]\n");
  755.       printf("Example: sjturbo pv\n");
  756.       printf("\n");
  757.       printf("operation            \"pv\" = program and verify\n");
  758.       printf("                     \"v\" = Verify only\n");
  759.       printf("                     \"uv\" = Verify UES only\n");
  760.       printf("                     Default to pv if operation is not entered.\n");                            
  761.       exit(1);
  762.    }
  763.  
  764.    /*3.02 set the initial condition of the parallel port*/
  765.    /*     All the port_pins defined on lattice.h will be controlled by
  766.           ispstream_pump(). The rest can be initialized here either to
  767.           HIGH or LOW and won't be altered by isptream_pump*/
  768.             
  769.       if (rcode == OK){        /*start programming and verification*/
  770.                 
  771.           if(!strcmp(strlwr(argv[1]),"uv")){                  /*3.05 What to do? uv=ues verify only*/
  772.               operation=verify_ues;                                      /*for verify ues only =1*/  
  773.               printf("\nStart Verify UES of ispLSI devices.......\n");}  
  774.           else if(!strcmp(strlwr(argv[1]),"v")){               /*v = verify only*/
  775.               operation=verify;
  776.               printf("\nStart Verify.......\n");}
  777.           else {                                               /*pv = program and verify: Default*/
  778.                   operation=prog_verify;
  779.                   printf("\nStart Program and Verify.......\n");
  780.                }    
  781.  
  782.    rcode = ispstream_pump(operation, &end);       /*3.05 add operation switch*/
  783.        }
  784.    if (rcode != OK) {
  785.       error_handler(rcode, str);
  786.       printf("\nFailed At Row %d Due To %s\n", end, str);
  787.       printf("\n");
  788.       printf("+-------+\n");
  789.       printf("| FAIL! |\n");
  790.       printf("+-------+\n");
  791.       return (-rcode);
  792.    } else {
  793.       printf("\n");
  794.       printf("+=======+\n");
  795.       printf("| PASS! |\n");
  796.       printf("+=======+\n");
  797.    }
  798.  
  799.    return(0);
  800.